package leo.peersim.abcast;

import leo.peersim.common.FSMOperationRequest;
import leo.peersim.common.LamportEvent;
import peersim.core.Node;

/**
 * 
 * @author leo
 * @version June 12, 2009
 */
public abstract class ABCastMessage extends LamportEvent {
	
	private final String transactionID;
	private final long senderTimestamp;
	private final Node senderNode;
	
	public ABCastMessage(String transactionID, Node senderNode, long senderTimestamp) {
		this.transactionID = transactionID;
		this.senderNode = senderNode;
		this.senderTimestamp = senderTimestamp;
	}
	
	public String getTransactionID() {
		return this.transactionID;
	}
	
	public Node getSenderNode() {
		return this.senderNode;
	}
	
	public long getLamportNodeID() {
		return this.senderNode.getID();
	}
	
	public long getLamportTimestamp() {
		return this.senderTimestamp;
	}
	
	@Override
	public String toString() {
		String s = "" + this.senderNode.getID() +"@" + this.senderTimestamp;
		return s;
	}
	
	//FIXME consider to move to a superclass
	public int getSizeInByte() {
		return 1; // FIXME
	}

}

/**
 * 
 * @author leo
 */
class Request extends ABCastMessage {
	
	private FSMOperationRequest payload;

	public Request(String transactionID, Node senderNode, long senderTimestamp, FSMOperationRequest clientRequest) {
		super(transactionID, senderNode, senderTimestamp);
		this.payload = clientRequest;
	}
	
	public FSMOperationRequest getContent() {
		return this.payload;
	}
	
	@Override
	public String toString() {
		return payload.getOperazione();
	}
}

/**
 * 
 * @author leo
 */
class Propose extends ABCastMessage {
	
	private final long proposedTimestamp;

	public Propose(String transactionID, Node senderNode, long senderTimestamp, long proposedTimestamp) {
		super(transactionID, senderNode, senderTimestamp);
		this.proposedTimestamp = proposedTimestamp;
	}
	
	public long getProposedTimestamp() {
		return this.proposedTimestamp;
	}

}

/**
 * 
 */
class Agree extends ABCastMessage {
	
	private final long agreedTimestamp;

	public Agree(String transactionID, Node senderNode, long senderTimestamp, long agreedTimestamp) {
		super(transactionID, senderNode, senderTimestamp);
		this.agreedTimestamp = agreedTimestamp;
	}
	
	public long getAgreedTimestamp() {
		return this.agreedTimestamp;
	}

}